home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
FishMarket 1.0
/
FishMarket v1.0.iso
/
fishies
/
201-225
/
disk_216
/
backdrop
/
src
/
backdrop.c
< prev
next >
Wrap
C/C++ Source or Header
|
1992-05-06
|
11KB
|
388 lines
/*
* Backdrop (C) Copyright Eddy Carroll 1989, may be Freely Redistributed
*
* Backdrop allows you to define a pattern which will then be displayed
* in the empty screen area behind all the windows (who said Macintosh? :-)
*
* Usage: Backdrop { -a# | -b# | -f | -p# | -q | -s | B1B2B3B4B5B6B7B8}
*
* If no parameters are given, the default is a half tone grey pattern.
*
* -a or -b followed by a number sets the foreground or background colour
* to the corresponding pen number (0 - 3)
*
* -f and -s select either a SMART_REFRESH or SIMPLE_REFRESH window to
* display the backdrop pattern in. The former gives fast screen updates,
* but uses up quite a bit of memory, whereas the latter uses up very
* little memory but is slower at updating the screen.
*
* -p followed by a number selects the built in pattern corresponding to that
* number. If you try and select a pattern number not available, you get
* the default.
*
* -q kills the background copy of Backdrop currently installed, if any.
*
* A list of 16 hex digits will be interpreted as a user defined pattern,
* which should be viewed as an 8x8 grid.
*
* The first time you run Backdrop, it installs itself in memory. Future
* invocations of Backdrop will merely tell this first copy about any
* changes in parameters, until the -q option is used to remove it. Note
* that all the parameters, including window type, can be changed even
* while Backdrop is currently running.
*
* Compiles under Lattice C V4.0
*
*/
#include <exec/types.h>
#include <graphics/gfxbase.h>
#include <graphics/gfxmacros.h>
#include <intuition/intuition.h>
#include <intuition/intuitionbase.h>
#include <libraries/dos.h>
#include <proto/exec.h>
#include <proto/graphics.h>
#include <proto/dos.h>
#include <proto/intuition.h>
#include <string.h>
#define tolower(c) ((c) >= 'A' && (c) <= 'Z' ? (c) + 'a' - 'A' : (c))
#define YES 1
#define NO 0
#define NUMPATS 19 /* Number of predefined patterns available */
#define REPEAT 9999 /* Special return value indicates reopen window */
#define UNSET -1 /* Indicates a parameter is currently unset */
#define htoi(c) (((c) >= 'A' ? (c) - 7 : (c)) & 0x0F) /* Hex to int */
struct IntuitionBase *IntuitionBase;
struct GfxBase *GfxBase;
ULONG BackGroundIO = 0;
char usage1[] = "\
Backdrop (C) Copyright Eddy Carroll 1989, adds backdrop to Workbench screen\n",
usage2[] = "\
Usage: Backdrop {-f | -p# | -q | -s | B1B2B3B4B5B6B7B8}\n\
\n\
-a# - Set foreground colour to specified pen #\n\
-b# - Set background colour to specified pen #\n",
usage3[] = "\
-f - Enable fast update (uses more memory)\n\
-p# - Use specified pattern # (1-5)\n\
-q - Remove backdrop from memory\n\
-s - Enable slow update\n\
B1B2B3B4B5B6B7B8 - 16 hex digits defining an 8x8 pattern\n\
\n> ";
char quit1[] = "Backdrop removed.\n";
char quit2[] = "Backdrop not installed.\n";
char Portname[] = "Backdrop";
struct Pattern {
UWORD value[8];
} Patterns[] = {
{ 0x5555,0xAAAA,0x5555,0xAAAA,0x5555,0xAAAA,0x5555,0xAAAA }, /* Check */
{ 0xFFFF,0x4040,0x4040,0x4040,0xFFFF,0x0404,0x0404,0x0404 }, /* Brick */
{ 0x8888,0x0000,0x0000,0x0000,0x8888,0x0000,0x0000,0x0000 },
{ 0x8888,0x0000,0x2222,0x0000,0x8888,0x0000,0x2222,0x0000 },
{ 0xAAAA,0x0000,0xAAAA,0x0000,0xAAAA,0x0000,0xAAAA,0x0000 },
{ 0xAAAA,0x0000,0x5555,0x0000,0xAAAA,0x0000,0x5555,0x0000 },
{ 0x8888,0x2222,0x8888,0x2222,0x8888,0x2222,0x8888,0x2222 },
{ 0xAAAA,0xAAAA,0x5555,0x5555,0xAAAA,0xAAAA,0x5555,0x5555 },
{ 0xCCCC,0x3333,0xCCCC,0x3333,0xCCCC,0x3333,0xCCCC,0x3333 },
{ 0xFFFF,0x8181,0xBDBD,0xA5A5,0xA5A5,0xBDBD,0x8181,0xFFFF },
{ 0xFEFE,0x8282,0xBABA,0xAAAA,0xBABA,0x8282,0xFEFE,0x0000 },
{ 0x9999,0xCCCC,0x6666,0x3333,0x9999,0xCCCC,0x6666,0x3333 },
{ 0x9999,0x3333,0x6666,0xCCCC,0x9999,0x3333,0x6666,0xCCCC },
{ 0x0000,0x4444,0x2828,0x1010,0x2828,0x4444,0x0000,0x0000 },
{ 0x0000,0x5454,0x0202,0x5858,0x1A1A,0x4040,0x2A2A,0x0000 },
{ 0xAAAA,0x4444,0xAAAA,0x0000,0xAAAA,0x4444,0xAAAA,0x0000 },
{ 0xC3C3,0x6666,0x3C3C,0x1818,0x3C3C,0x6666,0xC3C3,0x8181 },
{ 0xDBDB,0x6666,0x3C3C,0x9999,0x9999,0x3C3C,0x6666,0xDBDB },
{ 0x6666,0xF0F0,0x9999,0x0F0F,0x6666,0xF0F0,0x9999,0x0F0F },
{ 0xFFFF,0xFFFF,0xFFFF,0xFFFF,0xFFFF,0xFFFF,0xFFFF,0xFFFF }
};
struct MyMsgPort {
struct MsgPort mp; /* A genuine message port */
struct Pattern pat; /* Current pattern */
ULONG windowflags; /* Flags for our window */
UBYTE foreground,background; /* Colours for window */
} port;
typedef struct MessagePort MP;
typedef struct MyMsgPort MyMP;
typedef struct IntuiMessage IM;
#define WINDOWFLAGS (BORDERLESS | BACKDROP)
struct NewWindow nw = {
0,0,
320,200, /* Max dimensions will be filled in at run time */
0,1, /* These colours are also filled in at run time */
REFRESHWINDOW,
NULL, /* Window flags will be filled in at run time */
NULL, NULL,
NULL,
NULL, NULL,
0,0,0,0,
WBENCHSCREEN
};
/*
* The start of the program. All main does is interpret the command line
* parameters, and then determine whether there is already a copy of Backdrop
* running or not. If there isn't, a public message port is set up for
* future reference, else the other copy of Backdrop is informed of the
* changes to the parameters.
*
*/
void main(argc,argv)
int argc;
char *argv[];
{
int quit = NO, error = NO;
UWORD n,i,j;
MyMP *myport;
struct Task *FindTask(), *othertask;
char *p;
int doback();
void resloop();
BPTR stdout;
stdout = Output();
/* Check to see if we are already running. If we are, initialise
* contents of our local port structure with the current contents,
* else initialise them to default values.
*/
if ((myport = (MyMP *)FindPort(Portname)) == NULL) {
/* --- First time being run --- */
port.foreground = 1; /* Default pen colour */
port.background = 0; /* Default background col */
port.windowflags = SMART_REFRESH | WINDOWFLAGS; /* Window type */
port.pat = Patterns[0]; /* Default pattern */
port.mp.mp_Node.ln_Name = Portname; /* Set the port name */
port.mp.mp_SigBit = AllocSignal(-1L); /* Get signal # for port */
} else {
/* --- Already running a copy --- */
port = *myport; /* Get copy of current contents */
}
/* Now parse command line, updating parameters as necessary */
while (argc > 1) {
if (argv[1][0] == '-') {
n = atoi(&argv[1][2]); /* Get possible second parameter */
switch (tolower(argv[1][1])) {
case 'a':
port.foreground = n;
break;
case 'b':
port.background = n;
break;
case 'p':
if (n < 0 || n > NUMPATS-1)
n = 0;
port.pat = Patterns[n];
break;
case 'q':
quit = YES;
break;
case 'f':
port.windowflags = WINDOWFLAGS | SMART_REFRESH;
break;
case 's':
port.windowflags = WINDOWFLAGS | SIMPLE_REFRESH;
break;
default:
error = YES;
break;
}
} else if ((strlen(p = argv[1])) == 16) {
/* Convert 16 digit hex value into pattern */
for (i = 0; i < 8; i++) {
for (n = 0, j = 0; j < 2; j++,p++) {
n = n<<4 | htoi(*p);
}
port.pat.value[i] = n<<8 | n;
}
} else
error = YES;
if (error) {
Write(stdout,usage1,sizeof(usage1));
Write(stdout,usage2,sizeof(usage2));
Write(stdout,usage3,sizeof(usage3));
exit(10);
}
argv++;
argc--;
}
/* Now local copy of port contains an up-to-date copy of the
* current settings
*/
if (myport == NULL) {
/* --- First time being run --- */
if (quit) {
Write(stdout,quit2,sizeof(quit2));
exit(10); /* No work to do if backdrop not active already */
}
Write(stdout,usage1,sizeof(usage1));
AddPort(&port); /* Make our port public */
/* Detach this process from CLI, and setup process ID in port */
if (!res("Backdrop",4,resloop,4000))
RemPort(&port);
exit(0);
} else {
othertask = myport->mp.mp_SigTask;
/* If quit, tell the other copy to quit */
if (quit) {
Write(stdout,quit1,sizeof(quit1));
Signal(othertask, SIGBREAKF_CTRL_C);
exit(0);
}
/* Else we have a new pattern to install */
Forbid(); /* Stop other copy trying to access the array */
*myport = port; /* Copy updated parameters back to global store */
Permit();
Signal(othertask, SIGBREAKF_CTRL_F); /* Force screen update */
exit(0);
}
}
/*
* This is the main loop. It just keeps looping around, until it is told
* to exit (via a special return value from doback()). When it returns,
* it actually is returning to AmigaDOS() which will then remove it from
* the system.
*
*/
void resloop()
{
port.mp.mp_SigTask = FindTask(0L); /* Set pointer to our task */
while (doback() == REPEAT) /* Do intuition stuff */
;
/* We got some kind of exit code, so clean up */
RemPort(&port); /* Kill our public port */
}
/*
* This routine is where all the actual work gets done. A backdrop window
* is opened on the workbench screen, and filled with the current pattern.
* Then it waits for messages from Intuition saying the window needs to be
* refreshed, and for signals from other invocations of Backdrop. A CTRL-C
* signal causes Backdrop to remove itself, and CTRL-F forces the screen
* to be updated. The return value is an error code, in case some resources
* couldn't be allocated (0 or 10).
*
*/
#define OLIB(a,b) ((a = (struct a *)OpenLibrary(b,33L)) == NULL)
int doback()
{
struct Window *win;
struct RastPort *rp;
struct Screen *scr;
IM *msg;
int err = 10, xmax, ymax,;
ULONG signal,lock;
if (OLIB(IntuitionBase,"intuition.library"))
goto err1;
if (OLIB(GfxBase,"graphics.library"))
goto err2;
/* Now find the maximum size for our window by peeking at the dimensions
* of the Workbench screen. If no workbench screen is open, we exit.
*/
lock = LockIBase(0L);
for (scr = IntuitionBase->FirstScreen; scr; scr = scr->NextScreen) {
if ((scr->Flags & SCREENTYPE) == WBENCHSCREEN) {
xmax = scr->Width;
ymax = scr->Height;
break;
}
}
UnlockIBase(lock);
if (scr == NULL)
goto err2; /* If couldn't find workbench screen, we fail */
nw.Width = xmax;
nw.Height = ymax;
nw.Flags = port.windowflags;
if ((win = OpenWindow(&nw)) == NULL)
goto err3;
err = 0; /* Everything opened ok, so indicate no error */
rp = win->RPort;
SetDrMd(rp,JAM2);
SetAfPt(rp,&port.pat.value[0],3); /* Set area pattern */
#define IDCMPMASK (1<<win->UserPort->mp_SigBit)
#define CTRL_C (SIGBREAKF_CTRL_C)
#define CTRL_F (SIGBREAKF_CTRL_F)
while (1) {
SetAPen(rp,port.foreground);
SetBPen(rp,port.background);
RectFill(rp,0,0,xmax,ymax);
signal = Wait(CTRL_C | CTRL_F | IDCMPMASK);
/* If we got a CTRL_C, break out of this loop */
if (signal & CTRL_C)
break;
/* Else was CTRL_F or a refresh event from Intuition */
if (signal & IDCMPMASK) {
/* Flush Intuition messages */
while ((msg = (IM *)GetMsg(win->UserPort)) != NULL)
ReplyMsg(msg);
}
/* Now check if user wants a different sort of window type */
if (nw.Flags != port.windowflags) {
err = REPEAT; /* Indicate we want to reopen window */
break;
}
/* Else loop back to start, and force redraw of window */
}
/* We get down to here if a CTRL_C is received */
err4:
CloseWindow(win);
err3:
CloseLibrary(GfxBase);
err2:
CloseLibrary(IntuitionBase);
err1:
return(err);
}
/*
* These definitions just stop the corresponding library routines getting
* pulled in, which helps keep the code size down.
*/
int brk(){return(0);}
void MemCleanup(){}
void chkabort(){}